package com.wangc.study.stream;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @program: study
 * @description: Stream 操作
 * @author: sk_wangc
 * @create: 2020-05-21 15:47
 **/
public class StreamTest {

    public static void main(String[] args) {


        //如果调用的方法返回的结果是Stream对象就意味着是一个中间操作
        Arrays.asList(1,2,3,4,5,6,7,8).stream().filter((x)->x%2==0).forEach(System.out::println);
        //求结果集中所有偶像的和
        long count = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().filter((x) -> x % 2 == 0).count();
        System.out.println(count);//个数
        //IntStream 可以求和，里面提供了sum方法，所以可以先将 Stream -> IntSteam
        int count1 = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().filter((x) -> x % 2 == 0).mapToInt(x->x).sum();
        System.out.println(count1);
        //求集合中的最大值
        System.out.println(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().max((a, b) -> a - b).get());
        //求集合的最小值
        System.out.println(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().min((a, b) -> a - b).get());

        Optional<Integer> any = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().filter(x -> x % 2 == 0).findAny();
        System.out.println(any.get());
        Optional<Integer> first = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().filter(x -> x % 2 == 0).findFirst();
        System.out.println(first.get());
        //报错，findFirst没有找到的时候，会返回一个空的Optional
       // Optional<Integer> first1 = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().filter(x -> x % 10 == 7).findFirst();
        //System.out.println(first1.get());

        //为什么运行了只打印了两次“运行”？
        //理解执行逻辑，它是先取1执行fileter,再执行findFirst,再取2再执行，而不是每个元素都执行完filter再执行findFirst  重点
        Stream<Integer> integerStream = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().filter(i -> {
            System.out.println("运行" + i);
            return i % 2 == 0;
        });
        System.out.println(integerStream.findFirst());

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        //获取最大值和最小值但是不用min和max方法
        Optional min = list.stream().sorted().findFirst();//sorted 按照自然顺序排序
        System.out.println(min.get());
        Optional max = list.stream().sorted((a, b) -> b-a).findFirst();
        System.out.println(max.get());


        //按自然顺序排序
        Arrays.asList("java", "c#", "python", "scala").stream().sorted().forEach(System.out::println);
        //按长度排序--自定义比较器
        Arrays.asList("java", "c#", "python", "scala").stream().sorted((a,b)->a.length()-b.length()).forEach(System.out::println);

        //想将集合中的元素进行过滤同时返回一个集合对象
        List<Integer> integerList = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());//Collectors收集器，聚合操作
        integerList.forEach(System.out::println);

        //去重操作
        Arrays.asList(1, 2, 3, 4, 6, 4, 3, 2, 1).stream().distinct().forEach(System.out::println); //自带distinct去重
        Arrays.asList(1, 2, 3, 4, 6, 4, 3, 2, 1).stream().collect(Collectors.toSet()).forEach(System.out::println); //利用set无序不重复的特点去重

        //eg:打印20-30的集合数据
        Stream.iterate(1, x -> x + 1).limit(40).skip(20).limit(10).forEach(System.out::println); //skip 跳过


        //切割后求和，转换为stream式计算，代码特别精简，也是函数式编程的特点
        String str = "11,22,33,44,55";
        System.out.println(Stream.of(str.split(",")).mapToInt(x -> Integer.valueOf(x)).sum());
        System.out.println(Stream.of(str.split(",")).mapToInt(Integer::valueOf).sum()); //方法的引用

        System.out.println(Stream.of(str.split(",")).map(x -> Integer.valueOf(x)).mapToInt(x -> x).sum());
        System.out.println(Stream.of(str.split(",")).map(Integer::valueOf).mapToInt(x -> x).sum());


        //创建一组自定义对象
        String string = "java,scale,pyrhon";
        Stream.of(string.split(",")).map(x -> new StreamPerson(x)).forEach(System.out::println);
        Stream.of(string.split(",")).map(StreamPerson::new ).forEach(System.out::println);     //构造方法的引用
        Stream.of(string.split(",")).map(x->StreamPerson.bulid(x)).forEach(System.out::println);
        Stream.of(string.split(",")).map(StreamPerson::bulid).forEach(System.out::println);    //静态方法的引用


        //peek 操作中间值
        //将str中的每个值打印出来，同时求和
        System.out.println(Stream.of(str.split(",")).peek(System.out::println).mapToInt(Integer::valueOf).sum());


        //allMatch 返回此流所有元素是否满足条件  anyMatch  返回此流任何元素是否满足条件
        System.out.println(list.stream().allMatch(x -> x % 2 == 0));

        //concat


    }



}
